﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.Security;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;

namespace Lswweb.Domain
{
    public class Globals
    {
        /// <summary>
        /// 取得缓存
        /// </summary>
        public static ICacheManager GetCacheManage
        {
            get { return CacheFactory.GetCacheManager(); }
        }

        #region 公共属性

        /// <summary>
        /// 虚拟应用程序根目录
        /// </summary>
        public static string ApplicationPath
        {
            get
            {
                string applicationPath = HttpContext.Current.Request.ApplicationPath;

                if (applicationPath == "/")
                    return string.Empty;
                else
                    return applicationPath;
            }
        }

        /// <summary>
        /// 获取IP地址
        /// </summary>
        public static string IPAddress
        {
            get
            {
                string userIP;
                HttpRequest Request = HttpContext.Current.Request; // ForumContext.Current.Context.Request;
                // 如果使用代理，获取真实IP
                if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != "")
                    userIP = Request.ServerVariables["REMOTE_ADDR"];
                else
                    userIP = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                if (userIP == null || userIP == "")
                    userIP = Request.UserHostAddress;
                return userIP;
            }
        }

        #region Skin

        public static string GetSkinPath(string path)
        {
            return ApplicationPath + "/Themes/" + SiteContext.Current.Language + "/" + path.TrimStart('/');
        }

        #endregion

        #endregion

        #region String Builder

        public static string MD5(string input)
        {
            return FormsAuthentication.HashPasswordForStoringInConfigFile(input, "MD5");
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="input">要加密的字符串</param>
        /// <returns>加密字符串</returns>
        public static string Encrypt(string input)
        {
            if (string.IsNullOrEmpty(input))
                return string.Empty;

            System.Security.Cryptography.DES des = System.Security.Cryptography.DES.Create();
            des.Mode = System.Security.Cryptography.CipherMode.CBC;
            ICryptoTransform ct;
            MemoryStream ms;
            CryptoStream cs;
            byte[] byt;
            byte[] Key = new byte[8] { 56, 50, 55, 56, 56, 55, 49, 49 };
            byte[] IV = new byte[8] { 56, 50, 55, 56, 56, 55, 49, 49 };

            ct = des.CreateEncryptor(Key, IV);

            byt = Encoding.GetEncoding("GB2312").GetBytes(input); //根据 GB2312 编码对字符串处理，转换成 byte 数组

            ms = new MemoryStream();
            cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
            cs.Write(byt, 0, byt.Length);
            cs.FlushFinalBlock();

            cs.Close();

            byte[] answer = ms.ToArray();
            for (int j = 0; j < answer.Length; j++)
            {
                Console.Write(answer[j].ToString() + " ");
            }
            Console.WriteLine();
            return Convert.ToBase64String(ms.ToArray()); // 将加密的 byte 数组依照 Base64 编码转换成字符串
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="input">加密的字符串</param>
        /// <returns>译后字符串</returns>
        public static string Decrypt(string input)
        {
            if (string.IsNullOrEmpty(input))
                return string.Empty;

            System.Security.Cryptography.DES des = System.Security.Cryptography.DES.Create();
            des.Mode = System.Security.Cryptography.CipherMode.CBC;
            ICryptoTransform ct;
            MemoryStream ms;
            CryptoStream cs;
            byte[] byt;
            byte[] Key = new byte[8] { 56, 50, 55, 56, 56, 55, 49, 49 };
            byte[] IV = new byte[8] { 56, 50, 55, 56, 56, 55, 49, 49 };

            ct = des.CreateDecryptor(Key, IV);
            byt = Convert.FromBase64String(input); // 将 密文 以 Base64 编码转换成 byte 数组

            ms = new MemoryStream();
            cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
            cs.Write(byt, 0, byt.Length);
            cs.FlushFinalBlock();

            cs.Close();

            return Encoding.GetEncoding("GB2312").GetString(ms.ToArray()); // 将 明文 以 GB2312 编码转换成字符串
        }

        /// <summary>
        /// HTML编码解码
        /// </summary>
        /// <param name="formattedStr">已经进行HTML编码的字符串</param>
        /// <returns></returns>
        public static string HtmlDecode(string formattedStr)
        {
            if (string.IsNullOrEmpty(formattedStr))
                return formattedStr;
            return SiteContext.Current.Context.Server.HtmlDecode(formattedStr);
        }

        /// <summary>
        /// HTML编码
        /// </summary>
        /// <param name="formattedStr">要进行编码的字符串</param>
        /// <returns></returns>
        public static string HtmlEncode(string formattedStr)
        {
            if (string.IsNullOrEmpty(formattedStr))
                return formattedStr;
            return SiteContext.Current.Context.Server.HtmlEncode(formattedStr);
        }

        
        
        /// <summary>
        /// 截取字符串长度,一个中文长度为2
        /// </summary>
        /// <param name="cutStr">源字符串</param>
        /// <param name="length">截取的长度</param>
        /// <param name="endsWith">尾部附加修饰字符串</param>
        /// <returns>截取的字符串</returns>
        public static string Cut(string cutStr,int length,string endsWith)
        {
            if (string.IsNullOrEmpty(cutStr))
                return string.Empty;

            cutStr = ClearHtml(cutStr);
            Regex cnRegex = new Regex("[\u4e00-\u9fa5]+", RegexOptions.Compiled);
            Char[] list = cutStr.ToCharArray();
            Int32 tmplength = 0;
            for (int i = 0; i < list.Length; i++)
            {
                tmplength += cnRegex.IsMatch(list[i].ToString()) ? 2 : 1;
                if (tmplength > length)
                    return cutStr.Substring(0, i) + endsWith;
            }
            return cutStr;
        }
        public static string Cut(string cutStr, int length)
        {
            return Cut(cutStr, length, "...");
        }

        /// <summary>
        /// 清除字串的HTML格式
        /// </summary>
        /// <param name="Str"></param>
        /// <returns></returns>
        public static string ClearHtml(string str)
        {
            if (str != null && str != string.Empty && str != "")
                return Regex.Replace(str, "<[^>]*>", "");
            else
                return string.Empty;
        }

        /// <summary>
        /// 从字符串中提取图片的url
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static IList<string> RegexImagesUrl(string strHtml)
        {
            IList<string> urlList = new List<string>();
            System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex("<img(?<Attributes1>[\\s\\S]*?)src=(\"{1}|'{1}|)(?<picture>[^\\[^>]*?(gif|jpg|jpeg|bmp|bmp))(\"{1}|'{1}|)(?<Attributes2>[\\s\\S]*?)>");
                                                                                                   
            System.Text.RegularExpressions.Match match;
            for (match = regex.Match(strHtml); match.Success; match = match.NextMatch())
            {
                string url = match.Groups[5].Value;
                if (!string.IsNullOrEmpty(url) && urlList.IndexOf(url) == -1)
                    urlList.Add(url);
            }
            return urlList;
        }

        #endregion

        #region object Property Manage

        /// <summary>
        /// 取得某个对像的某个属性
        /// </summary>
        /// <param name="obj">对像</param>
        /// <param name="propertyName">属性名</param>
        /// <returns>返回对像属性的值</returns>
        public static object GetPropertyValue(object obj, string propertyName)
        {
            if (obj == null || string.IsNullOrEmpty(propertyName))
                return null;

            PropertyInfo property = obj.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
            if (property != null)
                return property.GetValue(obj, null);
            else
                return null;
        }

        /// <summary>
        /// 设置对像的某个属性值
        /// </summary>
        /// <param name="obj">要设置的对像</param>
        /// <param name="propertyName">要设置的属性名</param>
        /// <param name="value">设置的值</param>
        /// <returns>是否设置成功</returns>
        public static void SetPropertyValue(object obj, string propertyName, object value)
        {
            if (obj == null || string.IsNullOrEmpty(propertyName))
                return;

            PropertyInfo property = obj.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
            SetPropertyValue(obj, property, value);
        }
        public static void SetPropertyValue(object obj, PropertyInfo property, object value)
        {
            if (property == null || !property.CanWrite)
                return;
            if (property.PropertyType.IsEnum)
                property.SetValue(obj, Enum.Parse(property.PropertyType, Convert.ToString(value), true), null); //这个方法传入的值可以是字符型也可以是数值型
            else if (property.PropertyType.IsPrimitive || property.PropertyType.IsValueType)
                property.SetValue(obj, Convert.ChangeType(value, property.PropertyType), null);
            else
                property.SetValue(obj, value, null);
        }
        public static void SetPropertyValue(object[] obj, string propertyName, object value)
        {
            if (obj == null || string.IsNullOrEmpty(propertyName))
                return;

            for (int i = 0; i < obj.Length; i++)
                SetPropertyValue(obj[i], propertyName, value);
        }

        #endregion

        #region message or windows

        //可设置width height
        //public static void Open(string openUrl, string windowName, int width, int height, string scrollbars)
        //{
        //    StringBuilder script = new System.Text.StringBuilder();
        //    script.Append("function OpenWin(){");
        //    if (width >0 && height >0)
        //    {
        //        script.Append("var Top=(window.screen.Height-" + height + ")/2;");
        //        script.Append("var Left = (window.screen.Width-" + width + ")/2;");
        //        script.Append("window.open('" + openUrl + "','" + windowName + "','width=" + width + ",height=" + height + ",left='+Left+',top='+Top+',scrollbars=" + scrollbars + "');");
        //    }
        //    else
        //    {
        //        script.Append("window.open('" + openUrl + "','" + windowName + "','');");
        //    }
        //    script.Append("};");
        //    script.Append("OpenWin();");

        //    Page page = SiteContext.Current.Context.Handler as Page;
        //    page.ClientScript.RegisterStartupScript(typeof(Page), "Open", script.ToString(), true);
        //}

        #endregion

        #region DateTime

        public static string FormatDateTime(DateTime dateTime, DateTimeFormatMode formatMode)
        {
            if (dateTime == DateTime.MaxValue || dateTime == DateTime.MinValue)
                return string.Empty;

            switch (formatMode)
            {
                case DateTimeFormatMode.Date:
                    return dateTime.ToString(SiteSettings.Settings.DateFormat);
                case DateTimeFormatMode.Time:
                    return dateTime.ToString(SiteSettings.Settings.TimeFormat);
                default:
                    return dateTime.ToString(SiteSettings.Settings.DateTimeFormat);
            }
        }

        #endregion

        #region 文件相关操作

        /// <summary>
        /// 根据Url判断文件是否存在
        /// </summary>
        /// <param name="fileUrl">url</param>
        /// <returns></returns>
        public static bool FileExists(string fileUrl)
        {
            if (string.IsNullOrEmpty(fileUrl))
                return false;
            return File.Exists(GetFilePath(fileUrl));
        }
        /// <summary>
        /// 根据url判断目录是否存在
        /// </summary>
        /// <param name="DirectoryUrl">目录url</param>
        /// <param name="createDirectory">如果目录不存是是否进行建立目录，如果选择true那么此方法返回的值永远是true</param>
        /// <returns>返回目录是否存在</returns>
        public static bool DirectoryExists(string DirectoryUrl, bool createDirectory)
        {
            string directoryPath = GetFilePath(DirectoryUrl);
            bool label1 = Directory.Exists(directoryPath);
            if (createDirectory && !label1)
            {
                Directory.CreateDirectory(directoryPath);
                label1 = true;
            }
            return label1;
        }

        public static void DirectoryDelete(string directoryUrl)
        {
            string directoryPath = GetFilePath(directoryUrl);
            bool label1 = Directory.Exists(directoryPath);
            if (label1)
                Directory.Delete(directoryPath, true);
        }
 
        /// <summary>
        /// 取得Url的实际路径
        /// </summary>
        /// <param name="fileUrl">url</param>
        /// <returns></returns>
        public static string GetFilePath(string fileUrl)
        {
            if (fileUrl.IndexOf(@":\") != -1 && fileUrl.IndexOf("/") == -1)
                return fileUrl;
            string url = (fileUrl.IndexOf(ApplicationPath) >= 0) ? fileUrl : ApplicationPath + fileUrl;
            return HttpContext.Current.Server.MapPath(url);
        }

        /// <summary>
        /// 验证文件扩展名是否正确
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="extensions">扩展名集合,格式如：gif|jpg|bmp|png</param>
        /// <returns></returns>
        public static bool ValidateFileExtension(string fileName, string extensions)
        {
            Regex regex = new Regex(".(" + extensions.ToLower() + ")$");
            return regex.Match(fileName.ToLower()).Success;
        }

        public static void FileDelete(string fileUrl)
        {
            if (FileExists(fileUrl))
                File.Delete(GetFilePath(fileUrl));
        }

        #endregion

        #region 其它方法

        /// <summary>
        /// 从网址中取得Url参数
        /// </summary>
        /// <returns></returns>
        public static string GetQueryStringByUrl(string queryKey, string url)
        {
            string queryString = string.Empty;
            Regex regex = new Regex("(^|[?&])" + queryKey + "=([^&]*)(&|$)");

            if (regex.IsMatch(url))
                queryString = regex.Match(url).Groups[2].Value;
            return queryString;
        }

        /// <summary>
        /// 生成随机数
        /// </summary>
        /// <param name="randomCount">生成随机数位数</param>
        /// <returns>随机数</returns>
        public static string RandomStr(int randomCount)
        {
            string Str_Num = string.Empty;
            string[] VarNum = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };

            int OldNum = -1;
            for (int i = 1; i <= randomCount; i++)
            {
                Random Rand = new Random(i * unchecked((int)DateTime.Now.Ticks));
                int NewNum = Rand.Next(VarNum.Length);
                if (NewNum == OldNum)
                {
                    return RandomStr(randomCount);
                }
                else
                {
                    Str_Num += VarNum[NewNum].ToString();
                    OldNum = NewNum;
                }
            }
            return Str_Num;
        }
        /// <summary>
        /// 生成时间+随机数的字符 
        /// </summary>
        /// <param name="dateTime">时间</param>
        /// <param name="randomCount">随机数位数</param>
        /// <returns>生成时间+随机数</returns>
        public static string RandomStr(DateTime dateTime,int randomCount)
        {
            string Str_Num = dateTime.ToString("yyyyMMddmmss").Remove(0,2);
            return Str_Num + RandomStr(randomCount);
        }

        #endregion
    }

    public enum DateTimeFormatMode
    {
        /// <summary>
        /// 日期
        /// </summary>
        Date,

        /// <summary>
        /// 时间格式
        /// </summary>
        Time,

        /// <summary>
        /// 日期时间格式
        /// </summary>
        DateTime
    }
}
